package com.zhangfb95.crosschain.server.controller;

import com.zhangfb95.crosschain.infra.exception.BusinessException;
import com.zhangfb95.crosschain.infra.model.Result;
import com.zhangfb95.crosschain.protocol.exc.ExcAccountService;
import com.zhangfb95.crosschain.protocol.exc.request.GetAccountExcReq;
import com.zhangfb95.crosschain.protocol.exc.request.SignExcReq;
import com.zhangfb95.crosschain.protocol.exc.response.GetAccountExcRes;
import com.zhangfb95.crosschain.protocol.exc.response.SignExcRes;
import com.zhangfb95.crosschain.server.infra.model.mapper.entity.ChainAccount;
import com.zhangfb95.crosschain.server.infra.model.mapper.entity.ChainAccountProperty;
import com.zhangfb95.crosschain.server.service.ChainAccountService;
import com.zhangfb95.crosschain.server.service.SignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhangfubing
 * @since 2023/10/18
 */
@RequestMapping("/exc/account")
@RestController
public class ExcAccountController implements ExcAccountService {

    @Autowired
    private ChainAccountService chainAccountService;
    @Autowired
    private SignService signService;

    @PostMapping("/getAccount")
    @Override
    public Result<GetAccountExcRes> getAccount(@RequestBody @Validated GetAccountExcReq req) {
        Long userId = req.getUserId();
        String chainPath = req.getChainPath();

        // 获取链账户信息
        ChainAccount chainAccount = chainAccountService.getDefaultChainAccount(userId, chainPath);
        if (chainAccount == null) {
            throw new BusinessException("not find chainAccount, userId=" + userId + ", chainPath=" + chainPath);
        }

        // 链账户属性信息
        Map<String, String> propertyMap;
        if (CollectionUtils.isEmpty(req.getPropertyKeys())) {
            propertyMap = Collections.emptyMap();
        } else {
            List<ChainAccountProperty> chainAccountProperties =
                    chainAccountService.listChainAccountProperty(chainAccount.getId(), req.getPropertyKeys());
            propertyMap = chainAccountProperties.stream().collect(Collectors.toMap(
                    ChainAccountProperty::getPropertyKey,
                    ChainAccountProperty::getPropertyValue
            ));
        }

        GetAccountExcRes res = new GetAccountExcRes()
                .setPublicKey(chainAccount.getPublicKey())
                .setPropertyMap(propertyMap);
        return Result.ok(res);
    }

    @PostMapping("/sign")
    @Override
    public Result<SignExcRes> sign(@RequestBody @Validated SignExcReq req) {
        Long userId = req.getUserId();
        String chainPath = req.getChainPath();

        // 获取链账户信息
        ChainAccount chainAccount = chainAccountService.getDefaultChainAccount(req.getUserId(), req.getChainPath());
        if (chainAccount == null) {
            throw new BusinessException("not find chainAccount, userId=" + userId + ", chainPath=" + chainPath);
        }

        // 生成签名
        byte[] signedBytes = signService.sign(chainAccount, req.getBytes());
        return Result.ok(new SignExcRes().setSignedBytes(signedBytes));
    }
}
